package com.gitee.wsl.android.ui.activity

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.Settings
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions.Companion.ACTION_REQUEST_PERMISSIONS
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions.Companion.EXTRA_PERMISSIONS
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.os.BuildCompat
import androidx.fragment.app.Fragment
import com.gitee.wsl.android.ext.device.globalAlarmManager
import com.gitee.wsl.android.ext.device.globalPowerManager
import com.gitee.wsl.android.ext.device.grantedAlarms
import com.gitee.wsl.android.ext.fillIntentArguments
import com.gitee.wsl.android.ext.store.PathExt.randomFilePathUri
import com.gitee.wsl.android.file.RequestAccess


abstract class ActivityIntentLauncher<Input, Output> {
    private lateinit var launcher: ActivityResultLauncher<Input>
    private lateinit var internalCallback: (resultCode: Int, data: Intent?) -> Unit

    protected abstract fun intent(context: Context, input: Input): Intent
    protected abstract fun onActivityResult(resultCode: Int, intent: Intent?): Output

    fun wire(activity: ComponentActivity) {
        launcher = activity.activityForResultLauncher(
            createIntent = ::intent
        ) { resultCode, intent ->
            internalCallback(resultCode, intent)
        }
    }

    fun launch(input: Input, onResult: (Output) -> Unit) {
        internalCallback = { resultCode, intent ->
            onResult(onActivityResult(resultCode, intent))
        }
        launcher.launch(input)
    }

    open fun registerLaunch(activity: ComponentActivity, input: Input, onResult: (Output) -> Unit) {
        val launcher = activity.activityRegistryForResultLauncher(createIntent = ::intent, onActivityResult = ::onActivityResult){
            onResult(it)
        }
        launcher.launch(input)
    }
}

open class ActivityResultContractsLauncher<Input, Output>(private val activityResultContract: ActivityResultContract<Input, Output>):
    ActivityIntentLauncher<Input, Output>() {
    override fun intent(context: Context, input: Input): Intent {
        return activityResultContract.createIntent(context,input)
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Output {
       return activityResultContract.parseResult(resultCode, intent)
    }

    override fun registerLaunch(activity: ComponentActivity, input: Input, onResult: (Output) -> Unit) {
        val launcher = activity.activityRegistryForResultLauncher(activityResultContract){
            onResult(it)
        }
        launcher.launch(input)
    }

}

class  StartActivityIntentLauncher< T : Activity>(vararg val params: Pair<String, Any?>) : ActivityIntentLauncher<Class<T>, Intent?>() {
    override fun intent(context: Context, input: Class<T>): Intent {
        val intent = Intent(context, input)
        if (params.isNotEmpty()) intent.fillIntentArguments(params)
        return intent
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Intent? {
        if (intent == null || resultCode != Activity.RESULT_OK) return null
        return intent
    }
}

inline fun <reified T : Activity> ComponentActivity.startActivity(vararg params: Pair<String, Any?>, noinline onResult: (Intent?) -> Unit) {
    StartActivityIntentLauncher<T>(*params).registerLaunch(this,T::class.java,onResult)//.launch(T::class.java,onResult)
}

inline fun <reified T : Activity> Fragment.startActivity(vararg params: Pair<String, Any?>, noinline onResult: (Intent?) -> Unit) {
    StartActivityIntentLauncher<T>(*params).registerLaunch(requireActivity(),T::class.java,onResult)//.launch(T::class.java,onResult)
}

inline fun <reified T : Activity> Launcher.startActivity(vararg params: Pair<String, Any?>, noinline onResult: (Intent?) -> Unit) {
    StartActivityIntentLauncher<T>(*params).registerLaunch(activity,T::class.java,onResult)//.launch(T::class.java,onResult)
}

typealias FileName = String

class CreateFileIntentLauncher(val mimeType: String = "application/csv") : ActivityIntentLauncher<FileName, Uri?>() {
    override fun intent(context: Context, input: FileName): Intent {
        return Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = mimeType
            putExtra(Intent.EXTRA_TITLE, input)

            // Optionally, specify a URI for the directory that should be opened in
            // the system file picker before your app creates the document.
            putExtra(
                DocumentsContract.EXTRA_INITIAL_URI,
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toURI()
            )
        }
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Uri? = intent?.data
}

fun ComponentActivity.createFile(fileName: FileName, mimeType: String = "application/csv", onResult: (Uri?) -> Unit)=
    CreateFileIntentLauncher(mimeType).registerLaunch(this,fileName,onResult)//.launch(fileName,onResult)

fun Fragment.createFile(fileName: FileName, mimeType: String = "application/csv", onResult: (Uri?) -> Unit)=
    requireActivity().createFile(fileName, mimeType, onResult)

fun Launcher.createFile(fileName: FileName, mimeType: String = "application/csv", onResult: (Uri?) -> Unit)=
    CreateFileIntentLauncher(mimeType).registerLaunch(activity,fileName,onResult)//.launch(fileName,onResult)


class FilePickerIntentLauncher (val mimeType: String = "*/*",val mineTypesFilter:Array<String>?=null)  : ActivityIntentLauncher<Unit, Uri?>() {
    override fun intent(context: Context, input: Unit): Intent = Intent(
        Intent.ACTION_OPEN_DOCUMENT
    ).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        mineTypesFilter?.let { putExtra(Intent.EXTRA_MIME_TYPES, it) }
        type = mimeType
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Uri? = intent?.data
}

fun ComponentActivity.filePicker(fileName: FileName, mineTypesFilter:Array<String>?=null, mimeType: String = "*/*", onResult: (Uri?) -> Unit) =
   // FilePickerIntentLauncher(mimeType).registerLaunch(this,Unit,onResult)
    FilePickerIntentLauncher(mimeType,mineTypesFilter).registerLaunch(this,Unit,onResult)

fun Fragment.filePicker(fileName: FileName, mineTypesFilter:Array<String>?=null, mimeType: String = "*/*", onResult: (Uri?) -> Unit) {
    requireActivity().filePicker(fileName,mineTypesFilter,mimeType, onResult)
}

fun Launcher.filePicker(fileName: FileName, mineTypesFilter:Array<String>?=null, mimeType: String = "*/*", onResult: (Uri?) -> Unit) =
    // FilePickerIntentLauncher(mimeType).registerLaunch(this,Unit,onResult)
    FilePickerIntentLauncher(mimeType,mineTypesFilter).registerLaunch(activity,Unit,onResult)


class OpenMultipleDocumentsLauncher (val mimeType: String = "*/*")  : ActivityResultContractsLauncher<Array<String>, List<Uri>>(ActivityResultContracts.OpenMultipleDocuments())

fun ComponentActivity.multFilePicker(mimeTypesFilter: Array<String>, mimeType: String = "*/*", onResult: (List<Uri>) -> Unit) =
    // FilePickerIntentLauncher(mimeType).registerLaunch(this,Unit,onResult)
    OpenMultipleDocumentsLauncher(mimeType).registerLaunch(this,mimeTypesFilter,onResult)

fun Fragment.multFilePicker(mimeTypesFilter: Array<String>, mimeType: String = "*/*", onResult: (List<Uri>) -> Unit) {
    requireActivity().multFilePicker(mimeTypesFilter,mimeType, onResult)
}

fun Launcher.multFilePicker(mimeTypesFilter: Array<String>, mimeType: String = "*/*", onResult: (List<Uri>) -> Unit) =
    // FilePickerIntentLauncher(mimeType).registerLaunch(this,Unit,onResult)
    OpenMultipleDocumentsLauncher(mimeType).registerLaunch(activity,mimeTypesFilter,onResult)


class FolderPickerIntentLauncher (val lastPath: String?=null)  : ActivityIntentLauncher<Unit, Uri?>() {
    override fun intent(context: Context, input: Unit): Intent = Intent(
        Intent.ACTION_OPEN_DOCUMENT_TREE
    ).apply {
        //addCategory(Intent.CATEGORY_OPENABLE)
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Uri? = intent?.data
}

fun ComponentActivity.folderPicker(oldPath: FileName, onResult: (Uri?) -> Unit) =
    // FilePickerIntentLauncher(mimeType).registerLaunch(this,Unit,onResult)
    FolderPickerIntentLauncher().registerLaunch(this,Unit,onResult)

fun Fragment.folderPicker(oldPath: FileName, onResult: (Uri?) -> Unit) {
    requireActivity().folderPicker(oldPath,onResult)
}

fun Launcher.folderPicker(oldPath: FileName, onResult: (Uri?) -> Unit) =
    // FilePickerIntentLauncher(mimeType).registerLaunch(this,Unit,onResult)
    FolderPickerIntentLauncher().registerLaunch(activity,Unit,onResult)


class RequestPermissionLauncher: ActivityIntentLauncher<String, Pair<String, Boolean>>() {
    private lateinit var mPermission: String

    override fun intent(context: Context, input: String): Intent {
        mPermission=input
        return Intent(ACTION_REQUEST_PERMISSIONS).apply {
            putExtra(EXTRA_PERMISSIONS, arrayOf(input))
        }
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Pair<String, Boolean> {
        if (intent == null || resultCode != Activity.RESULT_OK) return mPermission to false
        val grantResults = intent.getIntArrayExtra(ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS)

        return mPermission to
                if (grantResults == null || grantResults.isEmpty()) false
                else grantResults[0] == PackageManager.PERMISSION_GRANTED
    }
}

/*
fun ComponentActivity.requestPermission(permission: String,onResult: ( Pair<String, Boolean>) -> Unit)=
    RequestPermissionLauncher().registerLaunch(this,permission,onResult)//.launch(permission,onResult)

fun Fragment.requestPermission(permission: String, onResult: ( Pair<String, Boolean>) -> Unit)=
    requireActivity().requestPermission(permission, onResult)
*/

fun ComponentActivity.isPermissionGranted(permission: String):Boolean {
    return ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED
}

fun Fragment.isPermissionGranted(permission: String):Boolean {
    return ActivityCompat.checkSelfPermission(requireActivity(), permission) != PackageManager.PERMISSION_GRANTED
}

fun interface PermissionScope {
    fun requestPermissionAgain()
}

interface PermissionCheckCallBack{
    var onGranted: () -> Unit
    var onDenied: AppSettingsScope.(String) -> Unit
    var onShowRequestRationale: PermissionScope.(String) -> Unit
}

fun ComponentActivity.requestPermission(permission: String,
                                        onGranted: () -> Unit,
                                        onDenied: AppSettingsScope.(String) -> Unit,
                                        onShowRequestRationale: PermissionScope.(String) -> Unit={}) {
   RequestPermissionLauncher().registerLaunch(this,permission) { it ->
       val permission=it.first
       when {
           it.second -> onGranted()
           permission.isNotEmpty() && ActivityCompat.shouldShowRequestPermissionRationale(this, permission) ->
               onShowRequestRationale( PermissionScope { requestPermission(permission, onGranted, onDenied, onShowRequestRationale) },permission)
           else -> onDenied( AppSettingsScope { openAppSystemSetting() },permission )
       }
    }
}

fun ComponentActivity.requestPermission(permission: String,
                                        callback: PermissionCheckCallBack.()->Unit
                                        ) {
    val realCallback=object: PermissionCheckCallBack {
        override var onGranted: () -> Unit = {}
        override var onDenied: AppSettingsScope.(String) -> Unit = {}
        override var onShowRequestRationale: PermissionScope.(String) -> Unit= {}
    }
    callback(realCallback)
    requestPermission(permission,realCallback.onGranted,realCallback.onDenied,realCallback.onShowRequestRationale)
}

fun Fragment.requestPermission(permission: String, callback: PermissionCheckCallBack.()->Unit) {
    requireActivity().requestPermission(permission, callback)
}

class RequestMultiplePermissionLauncher: ActivityIntentLauncher<Array<String>, Map<String, Boolean>>() {
    private lateinit var mPermissions: Array<String>

    override fun intent(context: Context, input: Array<String>): Intent {
       mPermissions=input
       return Intent(
            ACTION_REQUEST_PERMISSIONS
        ).apply {
            putExtra(EXTRA_PERMISSIONS, input)
        }
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?): Map<String, Boolean> {
        val grantMap = mutableMapOf<String,Boolean>()
        if (intent == null || resultCode != Activity.RESULT_OK) return grantMap
        val grantResults = intent.getIntArrayExtra(ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS)
        mPermissions.forEachIndexed {index,mPermission->
            grantMap.plus(mPermission to
                    if (grantResults == null || grantResults.isEmpty()) false
                    else grantResults[index] == PackageManager.PERMISSION_GRANTED)
        }

        return grantMap
    }
}


fun ComponentActivity.requestMultiplePermission( permissions: Array<String>,onResult: ( Map<String, Boolean>) -> Unit)=
    RequestMultiplePermissionLauncher().registerLaunch(this,permissions  ,onResult)

fun Fragment.requestMultiplePermission(permissions: Array<String>, onResult: ( Map<String, Boolean>) -> Unit)=
    requireActivity().requestMultiplePermission(permissions, onResult)


/*@JvmName("requestMultiplePermission")
fun AppCompatActivity.requestPermission( permissions: List<String>,
                               onAllGranted: () -> Unit,
                               onDenied: AppSettingsScope.(List<String>) -> Unit,
                               onShowRequestRationale: MultiplePermissionsScope.(List<String>) -> Unit){
    requestPermission(permissions ,onAllGranted,onDenied, onShowRequestRationale)
}*/


interface MultiplePermissionCheckCallBack{
    var onAllGranted: () -> Unit
    var onDenied: AppSettingsScope.(List<String>) -> Unit
    var onShowRequestRationale: MultiplePermissionsScope.(List<String>) -> Unit
}


fun ComponentActivity.requestMultiplePermission(permissions: Array<String>,
                                                onAllGranted: () -> Unit,
                                                onDenied: AppSettingsScope.(List<String>) -> Unit,
                                                onShowRequestRationale: MultiplePermissionsScope.(List<String>) -> Unit) {
    val multiplePermissionLauncher = RequestMultiplePermissionLauncher()
    multiplePermissionLauncher.registerLaunch(this,permissions) { grantedMap ->
        if (grantedMap.containsValue(false)) {
            val deniedList = grantedMap.filter { !it.value }.map { it.key }.toList()
            val explainableList = deniedList.filter {
                ActivityCompat.shouldShowRequestPermissionRationale(this, it)
            }
            if (explainableList.isNotEmpty()) {
                onShowRequestRationale(MultiplePermissionsScope {
                    requestMultiplePermission(
                        explainableList.toTypedArray(),
                        onAllGranted,
                        onDenied,
                        onShowRequestRationale
                    )
                }, explainableList)
            } else {
                onDenied( AppSettingsScope { openAppSystemSetting() }, deniedList)
            }
        } else {
            onAllGranted()
        }
    }
}

@JvmName("requestMultiplePermission")
fun Fragment.requestMultiplePermission(vararg permissions: String,
                                       onAllGranted: () -> Unit,
                                       onDenied: AppSettingsScope.(List<String>) -> Unit,
                                       onShowRequestRationale: MultiplePermissionsScope.(List<String>) -> Unit){
    requestMultiplePermission(permissions as Array<String>,onAllGranted,onDenied, onShowRequestRationale)
}

@JvmName("requestMultiplePermission2")
fun Fragment.requestMultiplePermission(vararg permissions: String,callback: MultiplePermissionCheckCallBack.()->Unit){
    val realCallback=object: MultiplePermissionCheckCallBack {
        override var onAllGranted: () -> Unit ={}

        override var onDenied: AppSettingsScope.(List<String>) -> Unit = {}

        override var onShowRequestRationale: MultiplePermissionsScope.(List<String>) -> Unit={}
    }
    callback(realCallback)
    requestMultiplePermission(permissions as Array<String>,realCallback.onAllGranted,realCallback.onDenied, realCallback.onShowRequestRationale)
}

@JvmName("requestMultiplePermission3")
fun Fragment.requestMultiplePermission(permissions: Array<String>,
                                       onAllGranted: () -> Unit,
                                       onDenied: AppSettingsScope.(List<String>) -> Unit,
                                       onShowRequestRationale: MultiplePermissionsScope.(List<String>) -> Unit) {

    requireActivity().requestMultiplePermission(permissions, onAllGranted, onDenied, onShowRequestRationale)
}


fun interface MultiplePermissionsScope {
    fun requestDeniedPermissions()
}

class AppSettingsLauncher: ActivityIntentLauncher<Unit, Unit>() {
    override fun intent(context: Context, input: Unit): Intent =Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        .setData(Uri.fromParts("package", context.packageName, null))

    override fun onActivityResult(resultCode: Int, intent: Intent?) {
    }
}

fun interface AppSettingsScope {
    fun launchAppSettings()
}

fun ComponentActivity.openAppSystemSetting(onResult: (Unit) -> Unit={}){
    AppSettingsLauncher().registerLaunch(this,Unit, onResult)
}

fun Fragment.openAppSystemSetting(onResult: (Unit) -> Unit={}){
    requireActivity().openAppSystemSetting(onResult)
}

fun Launcher.openAppSystemSetting(onResult: (Unit) -> Unit={}){
    AppSettingsLauncher().registerLaunch(activity,Unit, onResult)
}

class AppNotificationSettingsLauncher: ActivityIntentLauncher<Unit, Unit>() {
    override fun intent(context: Context, input: Unit): Intent {
       return if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R)
        Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
            .setData(Uri.fromParts("package", context.packageName, null))
            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            .putExtra("app_uid", context.applicationInfo.uid)
        else
           Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
               .setData(Uri.fromParts("package", context.packageName, null))
    }

    override fun onActivityResult(resultCode: Int, intent: Intent?) {}
}

fun ComponentActivity.openAppNotificationSetting(onResult: (Unit) -> Unit={}){
    AppNotificationSettingsLauncher().registerLaunch(this,Unit,onResult)
}

fun Fragment.openAppNotificationSetting(onResult: (Unit) -> Unit={}){
    requireActivity().openAppNotificationSetting(onResult)
}

fun Launcher.openAppNotificationSetting(onResult: (Unit) -> Unit={}){
    AppNotificationSettingsLauncher().registerLaunch(activity,Unit,onResult)
}

class TakePictureLauncher: ActivityResultContractsLauncher<Uri, Boolean>(ActivityResultContracts.TakePicture())

fun ComponentActivity.takePicture(callback: ActivityResultCallback<Uri>){
    val cacheUri= randomFilePathUri(suffixes = "jpg")
    TakePictureLauncher().registerLaunch(this,cacheUri){
        if(it)
           callback.onActivityResult(cacheUri)
    }
}

fun Fragment.takePicture(callback: ActivityResultCallback<Uri>){
   requireActivity().takePicture(callback)
}

fun Launcher.takePicture(callback: ActivityResultCallback<Uri>){
    val cacheUri= randomFilePathUri(suffixes = "jpg")
    TakePictureLauncher().registerLaunch(activity,cacheUri){
        if(it)
            callback.onActivityResult(cacheUri)
    }
}

class TakePicturePictureLauncher: ActivityResultContractsLauncher<Void?, Bitmap?>(ActivityResultContracts.TakePicturePreview())

class CaptureVideoLauncher: ActivityResultContractsLauncher<Uri, Boolean>(ActivityResultContracts.CaptureVideo())

fun ComponentActivity.takeVideo(callback: ActivityResultCallback<Uri?>){
   val cacheUri= randomFilePathUri(suffixes = "mp4")
    TakePictureLauncher().registerLaunch(this,cacheUri){
             callback.onActivityResult(if(it) cacheUri else null)
    }
}

fun Fragment.takeVideo(callback: ActivityResultCallback<Uri?>){
    requireActivity().takeVideo(callback)
}

fun Launcher.takeVideo(callback: ActivityResultCallback<Uri?>){
    val cacheUri= randomFilePathUri(suffixes = "mp4")
    TakePictureLauncher().registerLaunch(activity,cacheUri){
        callback.onActivityResult(if(it) cacheUri else null)
    }
}

@BuildCompat.PrereleaseSdkCheck
class PhotoPickerLauncher: ActivityResultContractsLauncher<PhotoPicker.Args, List<Uri>>(PhotoPicker())

@BuildCompat.PrereleaseSdkCheck
fun ComponentActivity.photoPicker(args: PhotoPicker.Args, callback: ActivityResultCallback<List<Uri>>){
    PhotoPickerLauncher().registerLaunch(this,args){
        callback.onActivityResult(it)
    }
}

@BuildCompat.PrereleaseSdkCheck
fun Fragment.photoPicker(args: PhotoPicker.Args, callback: ActivityResultCallback<List<Uri>>){
   requireActivity().photoPicker(args, callback)
}

@BuildCompat.PrereleaseSdkCheck
fun Launcher.photoPicker(args: PhotoPicker.Args, callback: ActivityResultCallback<List<Uri>>){
    PhotoPickerLauncher().registerLaunch(activity,args){
        callback.onActivityResult(it)
    }
}

fun ComponentActivity.mediaPick(args: ActivityResultContracts.PickVisualMedia.VisualMediaType, callback: ActivityResultCallback<List<Uri>>){
    return mediaMultiplePick(args,1,callback)
}

fun Fragment.mediaPick(args: ActivityResultContracts.PickVisualMedia.VisualMediaType, callback: ActivityResultCallback<List<Uri>>){
    requireActivity().mediaPick(args, callback)
}

fun Launcher.mediaPick(args: ActivityResultContracts.PickVisualMedia.VisualMediaType, callback: ActivityResultCallback<List<Uri>>){
    return mediaMultiplePick(args,1,callback)
}

fun ComponentActivity.mediaMultiplePick(args: ActivityResultContracts.PickVisualMedia.VisualMediaType,maxItems:Int, callback: ActivityResultCallback<List<Uri>>){
    val pickMultipleVisualMedia = registerForActivityResult(ActivityResultContracts.PickMultipleVisualMedia(maxItems),callback)

    pickMultipleVisualMedia.launch(PickVisualMediaRequest(args))
}

fun Fragment.mediaMultiplePick(args: ActivityResultContracts.PickVisualMedia.VisualMediaType,maxItems:Int, callback: ActivityResultCallback<List<Uri>>){
    requireActivity().mediaMultiplePick(args, maxItems,callback)
}

fun Launcher.mediaMultiplePick(args: ActivityResultContracts.PickVisualMedia.VisualMediaType, maxItems:Int, callback: ActivityResultCallback<List<Uri>>){
    val pickMultipleVisualMedia = activity.registerForActivityResult(ActivityResultContracts.PickMultipleVisualMedia(maxItems),callback)

    pickMultipleVisualMedia.launch(PickVisualMediaRequest(args))
}

class RequestStoragePermissionLauncher: ActivityResultContractsLauncher<RequestAccess.Args, Boolean>(
    RequestAccess()
)

fun ComponentActivity.requestStoragePermission(args: RequestAccess.Args, callback: ActivityResultCallback<Boolean>){
    RequestStoragePermissionLauncher().registerLaunch(this,args){
        callback.onActivityResult(it)
    }
}

fun Fragment.requestStoragePermission(args: RequestAccess.Args, callback: ActivityResultCallback<Boolean>){
   requireActivity().requestStoragePermission(args, callback)
}

fun Launcher.requestStoragePermission(args: RequestAccess.Args, callback: ActivityResultCallback<Boolean>){
    RequestStoragePermissionLauncher().registerLaunch(activity,args){
        callback.onActivityResult(it)
    }
}

@RequiresApi(Build.VERSION_CODES.S)
fun ComponentActivity.requestAlarm(callback: ActivityResultCallback<Boolean>){
    val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)
    intent.data = Uri.parse("package:" + this.packageName)
    simpleActivityForResultLauncher(intent){ _: Int, _: Intent?->
        callback.onActivityResult(globalAlarmManager.grantedAlarms)
    }
}

@RequiresApi(Build.VERSION_CODES.S)
fun Launcher.requestAlarm(callback: ActivityResultCallback<Boolean>){
    val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)
    intent.data = Uri.parse("package:" + activity.packageName)
    activity.simpleActivityForResultLauncher(intent){ _: Int, _: Intent?->
        callback.onActivityResult(globalAlarmManager.grantedAlarms)
    }
}

@SuppressLint("BatteryLife")
fun ComponentActivity.requestBatteryOptimizationException(callback: ActivityResultCallback<Boolean>){
    val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    intent.data = Uri.parse("package:" + this.packageName)
    simpleActivityForResultLauncher(intent){_: Int, _: Intent?->
        callback.onActivityResult(globalPowerManager.isIgnoringBatteryOptimizations(this.packageName))
    }
}

@SuppressLint("BatteryLife")
fun Launcher.requestBatteryOptimizationException(callback: ActivityResultCallback<Boolean>){
    val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    intent.data = Uri.parse("package:" + activity.packageName)
    activity.simpleActivityForResultLauncher(intent){_: Int, _: Intent?->
        callback.onActivityResult(globalPowerManager.isIgnoringBatteryOptimizations(activity.packageName))
    }
}

